package net.kts.attraction.subway.smallpass.process;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.util.Log;


import net.kts.attraction.subway.smallpass.model.LastPath;
import net.kts.attraction.subway.smallpass.model.PassLine;
import net.kts.attraction.subway.smallpass.model.PassStation;
import net.kts.attraction.subway.smallpass.model.infomation.MultiLineStation;
import net.kts.attraction.subway.smallpass.model.infomation.StationInfo;
import net.kts.attraction.subway.smallpass.model.infomation.StationTransfer;
import net.kts.attraction.subway.smallpass.model.infomation.TransferInfo;
import net.kts.attraction.subway.smallpass.process.check.SmallWayChecker;
import net.kts.attraction.subway.smallpass.process.thread.SmallWayDownDirectionThread;
import net.kts.attraction.subway.smallpass.process.thread.SmallWayUpDirectionThread;

public class SmallWayPass {

	// ?�승???�보??
	private Map<Integer, StationTransfer> stationTransferMap = new HashMap<Integer, StationTransfer>();

	// ??���? key, value = ??��??, ??���?
	private Map<Integer, StationInfo> stationInfoMap = new HashMap<Integer, StationInfo>();

	// 갈래�??�보    // key, value= 갈래�???��??, 갈래�??�보 model
	private Map<Integer, MultiLineStation> multiLineStationMap = new HashMap<Integer, MultiLineStation>();
	
	public SmallWayPass(Map<Integer, StationTransfer> stationTransferMap, Map<Integer, StationInfo> stationInfoMap,
			Map<Integer, MultiLineStation> multiLineStationMap) {
		
		this.stationTransferMap = stationTransferMap;
		this.stationInfoMap = stationInfoMap;
		this.multiLineStationMap = multiLineStationMap;
	}


	public void transferProcess(StationInfo prevStation, StationInfo currentStation, LastPath lastPath) {

		StationTransfer stationTransfer = stationTransferMap.get(currentStation.getStationCode());
		LastPath cloneLastPath = null;
		PassLine tempPassLine = null;
		PassStation tempPassStation = null;
		
		try {
			cloneLastPath = (LastPath) lastPath.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		double currTime = 0;

		if(prevStation.getUpStationCode() == currentStation.getStationCode() || currentStation.getDownStationCode() == prevStation.getStationCode()) {
			currTime = prevStation.getUpStationTime();
		}
		else {
			currTime = prevStation.getDownStationTime();
		}

		//			tempPassStation = settingPassStation(currentStation, currTime);
		//			cloneLastPath.getPassStationList().add(tempPassStation);
		//			cloneLastPath.setLastTime(cloneLastPath.getLastTime() + currTime);
		//			cloneLastPath.getStationSet().add(tempPassStation.getStationCode());

		cloneLastPath.getPassStationList().add(settingPassStation(currentStation, currTime));
		cloneLastPath.setLastTime(cloneLastPath.getLastTime() + currTime);
		cloneLastPath.getStationSet().add(currentStation.getStationCode());

		for(TransferInfo transferInfo : stationTransfer.getTransferInfoList()) {

			StationInfo stationInfo = this.stationInfoMap.get(transferInfo.getStationCode());

			
			
			
			// ?�래???�는???�재 ?�비???�는 ?�승?�보?�이??;; �?
			if(transferInfo.getStationCode() == 44444) {
				continue;
			}
			
			// ?�역??�?�� 출발?�려????�� 같을 경우 ?�스 || ?�재??�� �?�� ?�승??�� 같을 경우???�스
//			if(prevStation.getStationCode() == stationInfo.getStationCode()) {
//				continue;
//			}
			
			

			//?�선?�보 ??��
			// �?�� ?�선 ?�보 기입
			
//			if(stationInfo == null){
//				Log.d("kts_null", "curr : " + currentStation.getStationCode() + " stationInfo :" + stationInfo);
//			}
			
			double time = SmallWayChecker.timeChecker.transferTimeCheck(currentStation.getStationCode(), currentStation.getLineNum(), stationInfo.getLineNum());
			tempPassLine = settingPassLine(currentStation, transferInfo.getLinenum(), transferInfo.getStationCode(), time, 3); // ?�승 
			
			cloneLastPath.getPassLineList().add(tempPassLine);
			cloneLastPath.setLastTime(cloneLastPath.getLastTime() + time);
			cloneLastPath.getStationSet().add(stationInfo.getStationCode());
			//?�승?�는경우!
//			if(currentStation.getStationCode() != stationInfo.getStationCode()) {
//				
//				double tempTime = 0;
//				
//				if(prevStation.getUpStationCode() == currentStation.getStationCode()) {
//					tempTime = prevStation.getUpStationTime();
//				}
//				else {
//					tempTime = prevStation.getDownStationTime();
//				}
//				
//				tempPassStation = settingPassStation(currentStation, tempTime);
//				cloneLastPath.getPassStationList().add(tempPassStation);
//				cloneLastPath.setLastTime(cloneLastPath.getLastTime() + tempTime);
//				cloneLastPath.getStationSet().add(tempPassStation.getStationCode());
//			}
			
		
//			tempPassStation = settingPassStation(stationInfo, time);
//			cloneLastPath.getPassStationList().add(tempPassStation);
//			cloneLastPath.setLastTime(cloneLastPath.getLastTime() + time);
			//?�재 ?�선 ??��
			
			
			cloneLastPath.getStationSet().add(currentStation.getStationCode());

			// 갈래길이??
//			if(SmallWayChecker.multiLineChecker.isMultiLine(stationInfo.getStationCode())) {
//				
//					this.multiLineProcess(prevStation, stationInfo, cloneLastPath);
//				
//			}
			// ?�니??그냥 ?�ㄱ
//			else {
//				if(prevStation.getStationCode() == currentStation.getStationCode() || prevStation.getStationCode() == currentStation.getStationCode()) {
//					
//						threadSingleStart(currentStation, prevStation, cloneLastPath);
//					
//				}
				
			// ?�승?�작???�서?�번?��? ?�재 ?�선번호�?같다�??��??�레??
			if(currentStation.getStationCode() == stationInfo.getStationCode()) {
//				threadTransferStart(currentStation, prevStation, cloneLastPath);
				continue;
			}
			
			
				this.threadStart(stationInfo,cloneLastPath);
				

//			}		 


		}


	}

	public void multiLineProcess(StationInfo prevStation, StationInfo currentStation, LastPath lastPath) {

		MultiLineStation multiLineStation=  this.multiLineStationMap.get(currentStation.getStationCode());

		// 갈래�?방향??모두 ?�릴�?��!
		List<Integer> nextList =  multiLineStation.getNextStationCodeList();
		LastPath cloneLastPath = null;


		StationInfo nextStationInfo = null;

		for(int indexI = 0 ; indexI < nextList.size(); ++indexI) {

			// ?�제 ?�른 갈래길이�??�레???�성?�면???�작?�켜??

			nextStationInfo = this.stationInfoMap.get(nextList.get(indexI));
			
			if(nextStationInfo.getStationCode() == prevStation.getStationCode()
					|| currentStation.getStationCode() == nextStationInfo.getStationCode()) {
				continue;
			}
			
			// 기존 ?�보 복사!
			try {
				cloneLastPath = (LastPath) lastPath.clone();
			} catch (CloneNotSupportedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			

			// 0 : 첫출발이???�요?�간???�음 ,    4 : 갈래�?
			// �?�� ?�선 ?�보 기입
			double time = SmallWayChecker.timeChecker.multiLineTimeCheck(currentStation.getStationCode(), currentStation.getStationCode(), nextStationInfo.getStationCode());
			cloneLastPath.getPassStationList().add(settingPassStation(nextStationInfo, time));
			cloneLastPath.setLastTime(cloneLastPath.getLastTime() + time);
			
			cloneLastPath.getStationSet().add(nextStationInfo.getStationCode());
			
		
			threadMultiLineStart(currentStation, nextStationInfo, cloneLastPath);
//			threadSingleStart(currentStation, nextStationInfo,cloneLastPath);
			
			//만약! 갈래길또???�승??��??
//			if(SmallWayChecker.multiLineChecker.isMultiLine(nextStationInfo.getStationCode())
//					|| SmallWayChecker.stationLineChecker.isLineMulti(nextStationInfo.getStationCode())) {
//				
//					threadSingleStart(currentStation, nextStationInfo,cloneLastPath);
//				
//				continue;
//			}

//			threadStart(nextStationInfo, cloneLastPath);
			
		}

	}

	// 출발! ?�킬?? ?�행?? ?�행??출발 ?�키???�레??
	public void threadStart(StationInfo stationInfo, LastPath lastPath) {
		
		// ?�료?�거 체크
		if(!SmallWayChecker.checkLastPath(lastPath)) {
			
			return;

		}
		
		Runnable upDirection = null;
		Runnable downDirection = null;
		
		if(checkLastPathStatus(lastPath) ) {
			return;
		}
		

		try {
			if(this.stationInfoMap.get(stationInfo.getUpStationCode()) != null && !lastPath.getStationSet().contains(stationInfo.getUpStationCode())) {
				upDirection = new SmallWayUpDirectionThread(this,(LastPath)lastPath.clone(), this.stationInfoMap.get(stationInfo.getUpStationCode()));
				SmallWayChecker.smallWayRunnableList.add(upDirection);
				
				Log.d("kts_thread_start", "double - " + stationInfo.getStationCode() + "->" +stationInfo.getUpStationCode() );
			}
			
			if(this.stationInfoMap.get(stationInfo.getDownStationCode()) != null && !lastPath.getStationSet().contains(stationInfo.getDownStationCode())) {
				downDirection = new SmallWayDownDirectionThread(this, (LastPath)lastPath.clone(), this.stationInfoMap.get(stationInfo.getDownStationCode()));
				SmallWayChecker.smallWayRunnableList.add(downDirection);
				
				Log.d("kts_thread_start", "double - " + stationInfo.getStationCode() + "->" +stationInfo.getDownStationCode() );
			}
			
			

			
			
			if(upDirection != null) {
//				upDirection.start();
				SmallWayChecker.executorService.execute(upDirection);
			}
			
			if(downDirection != null) {
//				downDirection.start();
				SmallWayChecker.executorService.execute(downDirection);
			}

		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	}
	
	// ?�승???�레??
	public void threadTransferStart(StationInfo current, StationInfo prev, LastPath lastPath) {
		
		Runnable runnable = null;

		if(checkLastPathStatus(lastPath)  ) {
			return;
		}
		// ?�료?�거 체크
		if(!SmallWayChecker.checkLastPath(lastPath)) {
			return;
		}
		
		try {
			
			//up
			if(current.getDownStationCode() == prev.getStationCode() && this.getStationInfo(current.getUpStationCode()) != null) {
				runnable = new SmallWayUpDirectionThread(this, (LastPath)lastPath.clone(), this.getStationInfo(current.getUpStationCode()));
				Log.d("kts_thread_start", "sing_trans - " + current.getStationCode() + "->" +current.getUpStationCode() );
			}
			// down
			else {
				if(this.getStationInfo(current.getDownStationCode()) != null) {
					runnable = new SmallWayDownDirectionThread(this, (LastPath)lastPath.clone(), this.getStationInfo(current.getDownStationCode()));
					Log.d("kts_thread_start", "sing_trans - " + current.getStationCode() + "->" +current.getDownStationCode() );
				}
				
			}
			

		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(runnable != null) {
			SmallWayChecker.executorService.execute(runnable);
		}

	}
	
	// 갈래길용 ?�레??;; ?�시 만들?�봄
	public void threadMultiLineStart(StationInfo current, StationInfo next, LastPath lastPath) {
		Runnable runnable = null;
		
		if(checkLastPathStatus(lastPath)  ) {
			return;
		}
		
		// ?�료?�거 체크
		if(!SmallWayChecker.checkLastPath(lastPath)) {
			
			return;

		}
		
		try {
			
			// up
			if(checkUpAndDown(current, next) == 1) {

				runnable = new SmallWayUpDirectionThread(this, (LastPath)lastPath.clone(), next);
				Log.d("kts_thread_start", "sing_multi - " + current.getStationCode() + "->" +next.getStationCode() );
			}
			// down
			else {
				runnable = new SmallWayDownDirectionThread(this, (LastPath)lastPath.clone(), next);
				Log.d("kts_thread_start", "sing - " + current.getStationCode() + "->" +next.getStationCode() );
			}
			
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(runnable != null) {
			SmallWayChecker.executorService.execute(runnable);
		}
		
	}
	
	// 갈래길용 ?�레??
	// current : 갈래�?  next : 갈래???�음??
	public void threadSingleStart(StationInfo current, StationInfo next, LastPath lastPath) {
		
		if(checkLastPathStatus(lastPath)  ) {
			return;
		}
		
		// ?�료?�거 체크
		if(!SmallWayChecker.checkLastPath(lastPath)) {
			
			return;

		}

		Runnable thread = null;
		try {
			if(checkUpAndDown(current, next) == 1) {
				
				if(current.getUpStationCode() == 29000) {
					
					thread = new SmallWayUpDirectionThread(this, (LastPath)lastPath.clone(), this.stationInfoMap.get(next.getStationCode()));
//					SmallWayChecker.smallWayThreadList.add(thread);
					SmallWayChecker.smallWayRunnableList.add(thread);
					
					Log.d("kts_thread_start", "sing - " + current.getStationCode() + "->" +next.getUpStationCode() );
				}
				else {
					if(this.stationInfoMap.get(current.getUpStationCode()) != null && !lastPath.getStationSet().contains(current.getUpStationCode())) {						
						
						thread = new SmallWayUpDirectionThread(this, (LastPath)lastPath.clone(), this.stationInfoMap.get(current.getUpStationCode()));
						SmallWayChecker.smallWayRunnableList.add(thread);
						Log.d("kts_thread_start", "sing - " + current.getStationCode() + "->" +next.getUpStationCode() );
					}
				}
				
				
			}
			else {
				
				if(current.getUpStationCode() == 29000) {
					thread = new SmallWayUpDirectionThread(this, (LastPath)lastPath.clone(), this.stationInfoMap.get(next.getStationCode()));
					SmallWayChecker.smallWayRunnableList.add(thread);
					Log.d("kts_thread_start", "sing - " + current.getStationCode() + "->" +next.getUpStationCode() );
				}
				else {
					if(this.stationInfoMap.get(current.getDownStationCode()) != null && !lastPath.getStationSet().contains(current.getDownStationCode())) {
						thread = new SmallWayDownDirectionThread(this, lastPath, this.stationInfoMap.get(current.getDownStationCode()));
						SmallWayChecker.smallWayRunnableList.add(thread);
						Log.d("kts_thread_start", "sing - " + current.getStationCode() + "->" +next.getUpStationCode() );
					}
				}
				
				
				
			}
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

//		Log.d("kts_thread_create", "threadSingleStart create count : " + SmallWayChecker.smallWayThreadList.size() + " cur station code : " + current.getStationCode() + " next station code : " + next.getStationCode());

		
		if( thread != null) {
//			thread.start();
			SmallWayChecker.executorService.execute(thread);
			
			//SmallWayChecker.executorService.
		}
		
		
	}
	
	// 갈래길용 up down 체크!!
	// 1?�면 up  2 ?�면 down
	public int checkUpAndDown(StationInfo current, StationInfo next) {
		
		if(next.getDownStationCode() == current.getStationCode()) {
			return 1;
		}
				
		return 2;
	}

	// �?�� ?�선 ?�보 객체 ?�성
	public PassLine settingPassLine(StationInfo stationInfo, int nextLine, int nextStationCode, double time, int type) {

		PassLine passLine = new PassLine();
		passLine.setStationCode(stationInfo.getStationCode());
		passLine.setTargetStationCode(nextStationCode);
		passLine.setLineNum(stationInfo.getLineNum());
		passLine.setDirection(nextLine);
		passLine.setTime(time);
		passLine.setType(type);

		return passLine;

	}


	// 거쳐???�선 ?�보 객체 ?�애??
	public PassStation settingPassStation(StationInfo stationInfo , double time) {

		PassStation passStation = new PassStation();
		
		
		passStation.setLineNum(stationInfo.getLineNum());
		passStation.setStationCode(stationInfo.getStationCode());
		passStation.setTime(time);

		return passStation;
	}


	public void threadRemove(Thread thread) {
		
		SmallWayChecker.removeThread(thread);
		//thread.stop();
		SmallWayChecker.threadCountCheck();
		
		Log.d("kts_thread", "thread remove count : " + SmallWayChecker.smallWayThreadList.size());
	}
	
	public void threadRemove(Runnable runnable) {
		
		SmallWayChecker.removeRunnable(runnable);
		//thread.stop();
		SmallWayChecker.runnableCountCheck();
		
//		Log.d("kts_thread", "thread remove count : " + SmallWayChecker.smallWayThreadList.size());
	}


	public StationInfo getStationInfo(int stationCode) {

		return this.stationInfoMap.get(stationCode);

	}
	
	
	public boolean isEndStation(int stationCode, LastPath lastPath) {
		List<TransferInfo> tList = lastPath.getEndList();
		if(tList != null) {
			
			for(TransferInfo transferInfo : tList) {
				if(transferInfo.getStationCode() == stationCode) {
					return true;
				}
			}
			
			
		}
		
		return false;
	}


	public boolean checkLastPathStatus(LastPath lastPath) {
		
//		if(lastPath.getLastTime() > 300) {
//			return true;
//		}
//		
//		if(lastPath.getPassStationList().size() > 100) {
//			return true;
//		}
		
		return false;
	}
}
